home *** CD-ROM | disk | FTP | other *** search
/ Usenet 1993 July / InfoMagic USENET CD-ROM July 1993.ISO / sources / unix / volume6 / rpc2 / part07 < prev    next >
Encoding:
Internet Message Format  |  1986-11-30  |  55.1 KB

  1. Subject:  v06i095:  Sun RPC Source (rpc2), Part07/11
  2. Newsgroups: mod.sources
  3. Approved: rs@mirror.UUCP
  4.  
  5. Submitted by: cca!SUN.COM!marks (Mark Stein)
  6. Mod.sources: Volume 6, Issue 95
  7. Archive-name: rpc2/Part07
  8.  
  9. [  "Don't blame me, I'm only the messenger."  -r$  ]
  10.  
  11. Sun RPC source (part 7 of 11).  This software package contains code
  12. and documentation for Revision 3.0 of the Sun Remote Procedure Call
  13. library.  In addition, a beta version of the XDR/RPC protocol compiler
  14. is included.  Comments about this latest release may be mailed to
  15. sun!rpc or rpc@sun.com.
  16.  
  17. Sun RPC is a product of Sun Microsystems, Inc. and is provided for
  18. unrestricted use provided that this legend is included on all tape
  19. media and as a part of the software program in whole or part.  Users
  20. may copy or modify Sun RPC without charge, but are not authorized to
  21. license or distribute it to anyone else except as part of a product or
  22. program developed by the user.
  23.  
  24. - - - - - - - - - C U T - H E R E - - - - - - - - - - - - - - - - - -
  25. #! /bin/sh
  26. # This is a shell archive, meaning:
  27. # 1. Remove everything above the #! /bin/sh line.
  28. # 2. Save the resulting text in a file.
  29. # 3. Execute the file with /bin/sh (not csh) to create:
  30. #    rpc/rpclib/pmap_clnt.c
  31. #    rpc/rpclib/pmap_getmaps.c
  32. #    rpc/rpclib/pmap_getport.c
  33. #    rpc/rpclib/pmap_prot.c
  34. #    rpc/rpclib/pmap_rmt.c
  35. #    rpc/rpclib/rpc_prot.c
  36. #    rpc/rpclib/svc.c
  37. # This archive created: Mon Jul 14 16:55:27 1986
  38. export PATH; PATH=/bin:/usr/bin:$PATH
  39. for d in rpc rpc/doc rpc/rpclib rpc/tools rpc/toys rpc/rpclib/profiled rpc/rpcgen rpc/rpcgen/test
  40. do
  41.     if test ! -d $d
  42.     then
  43.         echo "shar: Making directory $d"
  44.         mkdir $d
  45.         chmod 755 $d
  46.     fi
  47. done
  48. echo shar: "extracting 'rpc/rpclib/pmap_clnt.c'" '(4441 characters)'
  49. if test -f 'rpc/rpclib/pmap_clnt.c'
  50. then
  51.     echo shar: "will not over-write existing file 'rpc/rpclib/pmap_clnt.c'"
  52. else
  53. sed 's/^X//' << \SHAR_EOF > 'rpc/rpclib/pmap_clnt.c'
  54. X/*
  55. X * Sun RPC is a product of Sun Microsystems, Inc. and is provided for
  56. X * unrestricted use provided that this legend is included on all tape
  57. X * media and as a part of the software program in whole or part.  Users
  58. X * may copy or modify Sun RPC without charge, but are not authorized
  59. X * to license or distribute it to anyone else except as part of a product or
  60. X * program developed by the user.
  61. X * 
  62. X * SUN RPC IS PROVIDED AS IS WITH NO WARRANTIES OF ANY KIND INCLUDING THE
  63. X * WARRANTIES OF DESIGN, MERCHANTIBILITY AND FITNESS FOR A PARTICULAR
  64. X * PURPOSE, OR ARISING FROM A COURSE OF DEALING, USAGE OR TRADE PRACTICE.
  65. X * 
  66. X * Sun RPC is provided with no support and without any obligation on the
  67. X * part of Sun Microsystems, Inc. to assist in its use, correction,
  68. X * modification or enhancement.
  69. X * 
  70. X * SUN MICROSYSTEMS, INC. SHALL HAVE NO LIABILITY WITH RESPECT TO THE
  71. X * INFRINGEMENT OF COPYRIGHTS, TRADE SECRETS OR ANY PATENTS BY SUN RPC
  72. X * OR ANY PART THEREOF.
  73. X * 
  74. X * In no event will Sun Microsystems, Inc. be liable for any lost revenue
  75. X * or profits or other special, indirect and consequential damages, even if
  76. X * Sun has been advised of the possibility of such damages.
  77. X * 
  78. X * Sun Microsystems, Inc.
  79. X * 2550 Garcia Avenue
  80. X * Mountain View, California  94043
  81. X */
  82. X#ifndef lint
  83. Xstatic char sccsid[] = "@(#)pmap_clnt.c 1.1 86/02/03 Copyr 1984 Sun Micro";
  84. X#endif
  85. X
  86. X/*
  87. X * pmap_clnt.c
  88. X * Client interface to pmap rpc service.
  89. X *
  90. X * Copyright (C) 1984, Sun Microsystems, Inc.
  91. X */
  92. X
  93. X#include "types.h"
  94. X#include <netinet/in.h>
  95. X#include "xdr.h"
  96. X#include "auth.h"
  97. X#include "clnt.h"
  98. X#include "rpc_msg.h"
  99. X#include "pmap_prot.h" 
  100. X#include "pmap_clnt.h"
  101. X#include <sys/socket.h>
  102. X#include <sys/time.h>
  103. X#include <stdio.h>
  104. X#include <net/if.h>
  105. X#include <sys/ioctl.h>
  106. X#include <arpa/inet.h>
  107. X#define NAMELEN 255
  108. X
  109. Xstatic struct timeval timeout = { 5, 0 };
  110. Xstatic struct timeval tottimeout = { 60, 0 };
  111. Xstatic struct sockaddr_in myaddress;
  112. X
  113. Xvoid clnt_perror();
  114. X
  115. X
  116. X/*
  117. X * Set a mapping between program,version and port.
  118. X * Calls the pmap service remotely to do the mapping.
  119. X */
  120. Xbool_t
  121. Xpmap_set(program, version, protocol, port)
  122. X    u_long program;
  123. X    u_long version;
  124. X    u_long protocol;
  125. X    u_short port;
  126. X{
  127. X    struct sockaddr_in myaddress;
  128. X    int socket = -1;
  129. X    register CLIENT *client;
  130. X    struct pmap parms;
  131. X    bool_t rslt;
  132. X
  133. X    get_myaddress(&myaddress);
  134. X    client = clntudp_bufcreate(&myaddress, PMAPPROG, PMAPVERS,
  135. X        timeout, &socket, RPCSMALLMSGSIZE, RPCSMALLMSGSIZE);
  136. X    if (client == (CLIENT *)NULL)
  137. X        return (FALSE);
  138. X    parms.pm_prog = program;
  139. X    parms.pm_vers = version;
  140. X    parms.pm_prot = protocol;
  141. X    parms.pm_port = port;
  142. X    if (CLNT_CALL(client, PMAPPROC_SET, xdr_pmap, &parms, xdr_bool, &rslt,
  143. X        tottimeout) != RPC_SUCCESS) {
  144. X        clnt_perror(client, "Cannot register service");
  145. X        return (FALSE);
  146. X    }
  147. X    CLNT_DESTROY(client);
  148. X    (void)close(socket);
  149. X    return (rslt);
  150. X}
  151. X
  152. X/*
  153. X * Remove the mapping between program,version and port.
  154. X * Calls the pmap service remotely to do the un-mapping.
  155. X */
  156. Xbool_t
  157. Xpmap_unset(program, version)
  158. X    u_long program;
  159. X    u_long version;
  160. X{
  161. X    struct sockaddr_in myaddress;
  162. X    int socket = -1;
  163. X    register CLIENT *client;
  164. X    struct pmap parms;
  165. X    bool_t rslt;
  166. X
  167. X    get_myaddress(&myaddress);
  168. X    client = clntudp_bufcreate(&myaddress, PMAPPROG, PMAPVERS,
  169. X        timeout, &socket, RPCSMALLMSGSIZE, RPCSMALLMSGSIZE);
  170. X    if (client == (CLIENT *)NULL)
  171. X        return (FALSE);
  172. X    parms.pm_prog = program;
  173. X    parms.pm_vers = version;
  174. X    parms.pm_port = parms.pm_prot = 0;
  175. X    CLNT_CALL(client, PMAPPROC_UNSET, xdr_pmap, &parms, xdr_bool, &rslt,
  176. X        tottimeout);
  177. X    CLNT_DESTROY(client);
  178. X    (void)close(socket);
  179. X    return (rslt);
  180. X}
  181. X
  182. X/* 
  183. X * don't use gethostbyname, which would invoke yellow pages
  184. X */
  185. Xget_myaddress(addr)
  186. X    struct sockaddr_in *addr;
  187. X{
  188. X    int s;
  189. X    char buf[BUFSIZ];
  190. X    struct ifconf ifc;
  191. X    struct ifreq ifreq, *ifr;
  192. X    int len;
  193. X
  194. X    if ((s = socket(AF_INET, SOCK_DGRAM, 0)) < 0) {
  195. X        perror("get_myaddress: socket");
  196. X        exit(1);
  197. X    }
  198. X    ifc.ifc_len = sizeof (buf);
  199. X    ifc.ifc_buf = buf;
  200. X    if (ioctl(s, SIOCGIFCONF, (char *)&ifc) < 0) {
  201. X        perror("get_myaddress: ioctl (get interface configuration)");
  202. X        exit(1);
  203. X    }
  204. X    ifr = ifc.ifc_req;
  205. X    for (len = ifc.ifc_len; len; len -= sizeof ifreq) {
  206. X        ifreq = *ifr;
  207. X        if (ioctl(s, SIOCGIFFLAGS, (char *)&ifreq) < 0) {
  208. X            perror("get_myaddress: ioctl");
  209. X            exit(1);
  210. X        }
  211. X        if ((ifreq.ifr_flags & IFF_UP) &&
  212. X            ifr->ifr_addr.sa_family == AF_INET) {
  213. X            *addr = *((struct sockaddr_in *)&ifr->ifr_addr);
  214. X            addr->sin_port = htons(PMAPPORT);
  215. X            break;
  216. X        }
  217. X        ifr++;
  218. X    }
  219. X    close(s);
  220. X}
  221. SHAR_EOF
  222. if test 4441 -ne "`wc -c < 'rpc/rpclib/pmap_clnt.c'`"
  223. then
  224.     echo shar: "error transmitting 'rpc/rpclib/pmap_clnt.c'" '(should have been 4441 characters)'
  225. fi
  226. chmod 444 'rpc/rpclib/pmap_clnt.c'
  227. fi
  228. echo shar: "extracting 'rpc/rpclib/pmap_getmaps.c'" '(2732 characters)'
  229. if test -f 'rpc/rpclib/pmap_getmaps.c'
  230. then
  231.     echo shar: "will not over-write existing file 'rpc/rpclib/pmap_getmaps.c'"
  232. else
  233. sed 's/^X//' << \SHAR_EOF > 'rpc/rpclib/pmap_getmaps.c'
  234. X/*
  235. X * Sun RPC is a product of Sun Microsystems, Inc. and is provided for
  236. X * unrestricted use provided that this legend is included on all tape
  237. X * media and as a part of the software program in whole or part.  Users
  238. X * may copy or modify Sun RPC without charge, but are not authorized
  239. X * to license or distribute it to anyone else except as part of a product or
  240. X * program developed by the user.
  241. X * 
  242. X * SUN RPC IS PROVIDED AS IS WITH NO WARRANTIES OF ANY KIND INCLUDING THE
  243. X * WARRANTIES OF DESIGN, MERCHANTIBILITY AND FITNESS FOR A PARTICULAR
  244. X * PURPOSE, OR ARISING FROM A COURSE OF DEALING, USAGE OR TRADE PRACTICE.
  245. X * 
  246. X * Sun RPC is provided with no support and without any obligation on the
  247. X * part of Sun Microsystems, Inc. to assist in its use, correction,
  248. X * modification or enhancement.
  249. X * 
  250. X * SUN MICROSYSTEMS, INC. SHALL HAVE NO LIABILITY WITH RESPECT TO THE
  251. X * INFRINGEMENT OF COPYRIGHTS, TRADE SECRETS OR ANY PATENTS BY SUN RPC
  252. X * OR ANY PART THEREOF.
  253. X * 
  254. X * In no event will Sun Microsystems, Inc. be liable for any lost revenue
  255. X * or profits or other special, indirect and consequential damages, even if
  256. X * Sun has been advised of the possibility of such damages.
  257. X * 
  258. X * Sun Microsystems, Inc.
  259. X * 2550 Garcia Avenue
  260. X * Mountain View, California  94043
  261. X */
  262. X#ifndef lint
  263. Xstatic char sccsid[] = "@(#)pmap_getmaps.c 1.1 86/02/03 Copyr 1984 Sun Micro";
  264. X#endif
  265. X
  266. X/*
  267. X * pmap_getmap.c
  268. X * Client interface to pmap rpc service.
  269. X * contains pmap_getmaps, which is only tcp service involved
  270. X *
  271. X * Copyright (C) 1984, Sun Microsystems, Inc.
  272. X */
  273. X
  274. X#include "types.h"
  275. X#include <netinet/in.h>
  276. X#include "xdr.h"
  277. X#include "auth.h"
  278. X#include "clnt.h"
  279. X#include "rpc_msg.h"
  280. X#include "pmap_prot.h" 
  281. X#include "pmap_clnt.h"
  282. X#include <sys/socket.h>
  283. X#include <sys/time.h>
  284. X#include <netdb.h>
  285. X#include <stdio.h>
  286. X#include <errno.h>
  287. X#include <net/if.h>
  288. X#include <sys/ioctl.h>
  289. X#define NAMELEN 255
  290. X#define MAX_BROADCAST_SIZE 1400
  291. X
  292. Xextern int errno;
  293. Xstatic struct sockaddr_in myaddress;
  294. X
  295. X/*
  296. X * Get a copy of the current port maps.
  297. X * Calls the pmap service remotely to do get the maps.
  298. X */
  299. Xstruct pmaplist *
  300. Xpmap_getmaps(address)
  301. X     struct sockaddr_in *address;
  302. X{
  303. X    struct pmaplist *head = (struct pmaplist *)NULL;
  304. X    int socket = -1;
  305. X    struct timeval minutetimeout;
  306. X    register CLIENT *client;
  307. X
  308. X    minutetimeout.tv_sec = 60;
  309. X    minutetimeout.tv_usec = 0;
  310. X    address->sin_port = htons(PMAPPORT);
  311. X    client = clnttcp_create(address, PMAPPROG,
  312. X        PMAPVERS, &socket, 50, 500);
  313. X    if (client != (CLIENT *)NULL) {
  314. X        if (CLNT_CALL(client, PMAPPROC_DUMP, xdr_void, NULL, xdr_pmaplist,
  315. X            &head, minutetimeout) != RPC_SUCCESS) {
  316. X            clnt_perror(client, "pmap_getmaps rpc problem");
  317. X        }
  318. X        CLNT_DESTROY(client);
  319. X    }
  320. X    (void)close(socket);
  321. X    address->sin_port = 0;
  322. X    return (head);
  323. X}
  324. SHAR_EOF
  325. if test 2732 -ne "`wc -c < 'rpc/rpclib/pmap_getmaps.c'`"
  326. then
  327.     echo shar: "error transmitting 'rpc/rpclib/pmap_getmaps.c'" '(should have been 2732 characters)'
  328. fi
  329. chmod 444 'rpc/rpclib/pmap_getmaps.c'
  330. fi
  331. echo shar: "extracting 'rpc/rpclib/pmap_getport.c'" '(2946 characters)'
  332. if test -f 'rpc/rpclib/pmap_getport.c'
  333. then
  334.     echo shar: "will not over-write existing file 'rpc/rpclib/pmap_getport.c'"
  335. else
  336. sed 's/^X//' << \SHAR_EOF > 'rpc/rpclib/pmap_getport.c'
  337. X/*
  338. X * Sun RPC is a product of Sun Microsystems, Inc. and is provided for
  339. X * unrestricted use provided that this legend is included on all tape
  340. X * media and as a part of the software program in whole or part.  Users
  341. X * may copy or modify Sun RPC without charge, but are not authorized
  342. X * to license or distribute it to anyone else except as part of a product or
  343. X * program developed by the user.
  344. X * 
  345. X * SUN RPC IS PROVIDED AS IS WITH NO WARRANTIES OF ANY KIND INCLUDING THE
  346. X * WARRANTIES OF DESIGN, MERCHANTIBILITY AND FITNESS FOR A PARTICULAR
  347. X * PURPOSE, OR ARISING FROM A COURSE OF DEALING, USAGE OR TRADE PRACTICE.
  348. X * 
  349. X * Sun RPC is provided with no support and without any obligation on the
  350. X * part of Sun Microsystems, Inc. to assist in its use, correction,
  351. X * modification or enhancement.
  352. X * 
  353. X * SUN MICROSYSTEMS, INC. SHALL HAVE NO LIABILITY WITH RESPECT TO THE
  354. X * INFRINGEMENT OF COPYRIGHTS, TRADE SECRETS OR ANY PATENTS BY SUN RPC
  355. X * OR ANY PART THEREOF.
  356. X * 
  357. X * In no event will Sun Microsystems, Inc. be liable for any lost revenue
  358. X * or profits or other special, indirect and consequential damages, even if
  359. X * Sun has been advised of the possibility of such damages.
  360. X * 
  361. X * Sun Microsystems, Inc.
  362. X * 2550 Garcia Avenue
  363. X * Mountain View, California  94043
  364. X */
  365. X#ifndef lint
  366. Xstatic char sccsid[] = "@(#)pmap_getport.c 1.1 86/02/03 Copyr 1984 Sun Micro";
  367. X#endif
  368. X
  369. X/*
  370. X * pmap_getport.c
  371. X * Client interface to pmap rpc service.
  372. X *
  373. X * Copyright (C) 1984, Sun Microsystems, Inc.
  374. X */
  375. X
  376. X#include "types.h"
  377. X#include <netinet/in.h>
  378. X#include "xdr.h"
  379. X#include "auth.h"
  380. X#include "clnt.h"
  381. X#include "rpc_msg.h"
  382. X#include "pmap_prot.h" 
  383. X#include "pmap_clnt.h"
  384. X#include <sys/socket.h>
  385. X#include <sys/time.h>
  386. X#include <stdio.h>
  387. X#include <net/if.h>
  388. X#include <sys/ioctl.h>
  389. X#include <arpa/inet.h>
  390. X#define NAMELEN 255
  391. X
  392. Xstatic struct timeval timeout = { 5, 0 };
  393. Xstatic struct timeval tottimeout = { 60, 0 };
  394. X
  395. X/*
  396. X * Find the mapped port for program,version.
  397. X * Calls the pmap service remotely to do the lookup.
  398. X * Returns 0 if no map exists.
  399. X */
  400. Xu_short
  401. Xpmap_getport(address, program, version, protocol)
  402. X    struct sockaddr_in *address;
  403. X    u_long program;
  404. X    u_long version;
  405. X    u_long protocol;
  406. X{
  407. X    u_short port = 0;
  408. X    int socket = -1;
  409. X    register CLIENT *client;
  410. X    struct pmap parms;
  411. X
  412. X    address->sin_port = htons(PMAPPORT);
  413. X    client = clntudp_bufcreate(address, PMAPPROG,
  414. X        PMAPVERS, timeout, &socket, RPCSMALLMSGSIZE, RPCSMALLMSGSIZE);
  415. X    if (client != (CLIENT *)NULL) {
  416. X        parms.pm_prog = program;
  417. X        parms.pm_vers = version;
  418. X        parms.pm_prot = protocol;
  419. X        parms.pm_port = 0;  /* not needed or used */
  420. X        if (CLNT_CALL(client, PMAPPROC_GETPORT, xdr_pmap, &parms,
  421. X            xdr_u_short, &port, tottimeout) != RPC_SUCCESS){
  422. X            rpc_createerr.cf_stat = RPC_PMAPFAILURE;
  423. X            clnt_geterr(client, &rpc_createerr.cf_error);
  424. X        } else if (port == 0) {
  425. X            rpc_createerr.cf_stat = RPC_PROGNOTREGISTERED;
  426. X        }
  427. X        CLNT_DESTROY(client);
  428. X    }
  429. X    (void)close(socket);
  430. X    address->sin_port = 0;
  431. X    return (port);
  432. X}
  433. SHAR_EOF
  434. if test 2946 -ne "`wc -c < 'rpc/rpclib/pmap_getport.c'`"
  435. then
  436.     echo shar: "error transmitting 'rpc/rpclib/pmap_getport.c'" '(should have been 2946 characters)'
  437. fi
  438. chmod 444 'rpc/rpclib/pmap_getport.c'
  439. fi
  440. echo shar: "extracting 'rpc/rpclib/pmap_prot.c'" '(4003 characters)'
  441. if test -f 'rpc/rpclib/pmap_prot.c'
  442. then
  443.     echo shar: "will not over-write existing file 'rpc/rpclib/pmap_prot.c'"
  444. else
  445. sed 's/^X//' << \SHAR_EOF > 'rpc/rpclib/pmap_prot.c'
  446. X/*
  447. X * Sun RPC is a product of Sun Microsystems, Inc. and is provided for
  448. X * unrestricted use provided that this legend is included on all tape
  449. X * media and as a part of the software program in whole or part.  Users
  450. X * may copy or modify Sun RPC without charge, but are not authorized
  451. X * to license or distribute it to anyone else except as part of a product or
  452. X * program developed by the user.
  453. X * 
  454. X * SUN RPC IS PROVIDED AS IS WITH NO WARRANTIES OF ANY KIND INCLUDING THE
  455. X * WARRANTIES OF DESIGN, MERCHANTIBILITY AND FITNESS FOR A PARTICULAR
  456. X * PURPOSE, OR ARISING FROM A COURSE OF DEALING, USAGE OR TRADE PRACTICE.
  457. X * 
  458. X * Sun RPC is provided with no support and without any obligation on the
  459. X * part of Sun Microsystems, Inc. to assist in its use, correction,
  460. X * modification or enhancement.
  461. X * 
  462. X * SUN MICROSYSTEMS, INC. SHALL HAVE NO LIABILITY WITH RESPECT TO THE
  463. X * INFRINGEMENT OF COPYRIGHTS, TRADE SECRETS OR ANY PATENTS BY SUN RPC
  464. X * OR ANY PART THEREOF.
  465. X * 
  466. X * In no event will Sun Microsystems, Inc. be liable for any lost revenue
  467. X * or profits or other special, indirect and consequential damages, even if
  468. X * Sun has been advised of the possibility of such damages.
  469. X * 
  470. X * Sun Microsystems, Inc.
  471. X * 2550 Garcia Avenue
  472. X * Mountain View, California  94043
  473. X */
  474. X#ifndef lint
  475. Xstatic char sccsid[] = "@(#)pmap_prot.c 1.1 86/02/03 Copyr 1984 Sun Micro";
  476. X#endif
  477. X
  478. X/*
  479. X * pmap_prot.c
  480. X * Protocol for the local binder service, or pmap.
  481. X *
  482. X * Copyright (C) 1984, Sun Microsystems, Inc.
  483. X */
  484. X
  485. X#include "types.h"
  486. X#include "xdr.h"
  487. X#include "pmap_prot.h"
  488. X
  489. X#define NULL ((struct pmaplist *)0)
  490. X
  491. Xbool_t
  492. Xxdr_pmap(xdrs, regs)
  493. X    XDR *xdrs;
  494. X    struct pmap *regs;
  495. X{
  496. X
  497. X    if (xdr_u_long(xdrs, ®s->pm_prog) && 
  498. X        xdr_u_long(xdrs, ®s->pm_vers) && 
  499. X        xdr_u_long(xdrs, ®s->pm_prot))
  500. X        return (xdr_u_long(xdrs, ®s->pm_port));
  501. X    return (FALSE);
  502. X}
  503. X
  504. X/* 
  505. X * What is going on with linked lists? (!)
  506. X * First recall the link list declaration from pmap_prot.h:
  507. X *
  508. X * struct pmaplist {
  509. X *    struct pmap pml_map;
  510. X *    struct pmaplist *pml_map;
  511. X * };
  512. X *
  513. X * Compare that declaration with a corresponding xdr declaration that 
  514. X * is (a) pointer-less, and (b) recursive:
  515. X *
  516. X * typedef union switch (bool_t) {
  517. X * 
  518. X *    case TRUE: struct {
  519. X *        struct pmap;
  520. X *         pmaplist_t foo;
  521. X *    };
  522. X *
  523. X *    case FALSE: struct {};
  524. X * } pmaplist_t;
  525. X *
  526. X * Notice that the xdr declaration has no nxt pointer while
  527. X * the C declaration has no bool_t variable.  The bool_t can be
  528. X * interpreted as ``more data follows me''; if FALSE then nothing
  529. X * follows this bool_t; if TRUE then the bool_t is followed by
  530. X * an actual struct pmap, and then (recursively) by the 
  531. X * xdr union, pamplist_t.  
  532. X *
  533. X * This could be implemented via the xdr_union primitive, though this
  534. X * would cause a one recursive call per element in the list.  Rather than do
  535. X * that we can ``unwind'' the recursion
  536. X * into a while loop and do the union arms in-place.
  537. X *
  538. X * The head of the list is what the C programmer wishes to past around
  539. X * the net, yet is the data that the pointer points to which is interesting;
  540. X * this sounds like a job for xdr_reference!
  541. X */
  542. Xbool_t
  543. Xxdr_pmaplist(xdrs, rp)
  544. X    register XDR *xdrs;
  545. X    register struct pmaplist **rp;
  546. X{
  547. X    /*
  548. X     * more_elements is pre-computed in case the direction is
  549. X     * XDR_ENCODE or XDR_FREE.  more_elements is overwritten by
  550. X     * xdr_bool when the direction is XDR_DECODE.
  551. X     */
  552. X    bool_t more_elements;
  553. X    register int freeing = (xdrs->x_op == XDR_FREE);
  554. X    register struct pmaplist **next;
  555. X
  556. X    while (TRUE) {
  557. X        more_elements = (bool_t)(*rp != NULL);
  558. X        if (! xdr_bool(xdrs, &more_elements))
  559. X            return (FALSE);
  560. X        if (! more_elements)
  561. X            return (TRUE);  /* we are done */
  562. X        /*
  563. X         * the unfortunate side effect of non-recursion is that in
  564. X         * the case of freeing we must remember the next object
  565. X         * before we free the current object ...
  566. X         */
  567. X        if (freeing)
  568. X            next = &((*rp)->pml_next); 
  569. X        if (! xdr_reference(xdrs, (caddr_t *)rp,
  570. X            (u_int)sizeof(struct pmaplist), xdr_pmap))
  571. X            return (FALSE);
  572. X        rp = (freeing) ? next : &((*rp)->pml_next);
  573. X    }
  574. X}
  575. SHAR_EOF
  576. if test 4003 -ne "`wc -c < 'rpc/rpclib/pmap_prot.c'`"
  577. then
  578.     echo shar: "error transmitting 'rpc/rpclib/pmap_prot.c'" '(should have been 4003 characters)'
  579. fi
  580. chmod 444 'rpc/rpclib/pmap_prot.c'
  581. fi
  582. echo shar: "extracting 'rpc/rpclib/pmap_rmt.c'" '(10629 characters)'
  583. if test -f 'rpc/rpclib/pmap_rmt.c'
  584. then
  585.     echo shar: "will not over-write existing file 'rpc/rpclib/pmap_rmt.c'"
  586. else
  587. sed 's/^X//' << \SHAR_EOF > 'rpc/rpclib/pmap_rmt.c'
  588. X/*
  589. X * Sun RPC is a product of Sun Microsystems, Inc. and is provided for
  590. X * unrestricted use provided that this legend is included on all tape
  591. X * media and as a part of the software program in whole or part.  Users
  592. X * may copy or modify Sun RPC without charge, but are not authorized
  593. X * to license or distribute it to anyone else except as part of a product or
  594. X * program developed by the user.
  595. X * 
  596. X * SUN RPC IS PROVIDED AS IS WITH NO WARRANTIES OF ANY KIND INCLUDING THE
  597. X * WARRANTIES OF DESIGN, MERCHANTIBILITY AND FITNESS FOR A PARTICULAR
  598. X * PURPOSE, OR ARISING FROM A COURSE OF DEALING, USAGE OR TRADE PRACTICE.
  599. X * 
  600. X * Sun RPC is provided with no support and without any obligation on the
  601. X * part of Sun Microsystems, Inc. to assist in its use, correction,
  602. X * modification or enhancement.
  603. X * 
  604. X * SUN MICROSYSTEMS, INC. SHALL HAVE NO LIABILITY WITH RESPECT TO THE
  605. X * INFRINGEMENT OF COPYRIGHTS, TRADE SECRETS OR ANY PATENTS BY SUN RPC
  606. X * OR ANY PART THEREOF.
  607. X * 
  608. X * In no event will Sun Microsystems, Inc. be liable for any lost revenue
  609. X * or profits or other special, indirect and consequential damages, even if
  610. X * Sun has been advised of the possibility of such damages.
  611. X * 
  612. X * Sun Microsystems, Inc.
  613. X * 2550 Garcia Avenue
  614. X * Mountain View, California  94043
  615. X */
  616. X#ifndef lint
  617. Xstatic char sccsid[] = "@(#)pmap_rmt.c 1.1 86/02/03 Copyr 1984 Sun Micro";
  618. X#endif
  619. X
  620. X/*
  621. X * pmap_rmt.c
  622. X * Client interface to pmap rpc service.
  623. X * remote call and broadcast service
  624. X *
  625. X * Copyright (C) 1984, Sun Microsystems, Inc.
  626. X */
  627. X
  628. X#include "types.h"
  629. X#include <netinet/in.h>
  630. X#include "xdr.h"
  631. X#include "auth.h"
  632. X#include "clnt.h"
  633. X#include "rpc_msg.h"
  634. X#include "pmap_prot.h" 
  635. X#include "pmap_clnt.h"
  636. X#include <sys/socket.h>
  637. X#include <sys/time.h>
  638. X#include <stdio.h>
  639. X#include <errno.h>
  640. X#include <net/if.h>
  641. X#include <sys/ioctl.h>
  642. X#include <arpa/inet.h>
  643. X#define MAX_BROADCAST_SIZE 1400
  644. X
  645. Xextern int errno;
  646. Xstatic struct timeval timeout = { 3, 0 };
  647. X
  648. X/*
  649. X * Structures and XDR routines for parameters to and replys from
  650. X * the pmapper remote-call-service.
  651. X */
  652. X
  653. Xstruct rmtcallargs {
  654. X    u_long prog, vers, proc, arglen;
  655. X    caddr_t args_ptr;
  656. X    xdrproc_t xdr_args;
  657. X};
  658. Xstatic bool_t xdr_rmtcall_args();
  659. X
  660. Xstruct rmtcallres {
  661. X    u_long *port_ptr;
  662. X    u_long resultslen;
  663. X    caddr_t results_ptr;
  664. X    xdrproc_t xdr_results;
  665. X};
  666. Xstatic bool_t xdr_rmtcallres();
  667. X
  668. X/*
  669. X * pmapper remote-call-service interface.
  670. X * This routine is used to call the pmapper remote call service
  671. X * which will look up a service program in the port maps, and then
  672. X * remotely call that routine with the given parameters.  This allows
  673. X * programs to do a lookup and call in one step.
  674. X*/
  675. Xenum clnt_stat
  676. Xpmap_rmtcall(addr, prog, vers, proc, xdrargs, argsp, xdrres, resp, tout, port_ptr)
  677. X    struct sockaddr_in *addr;
  678. X    u_long prog, vers, proc;
  679. X    xdrproc_t xdrargs, xdrres;
  680. X    caddr_t argsp, resp;
  681. X    struct timeval tout;
  682. X    u_long *port_ptr;
  683. X{
  684. X    int socket = -1;
  685. X    register CLIENT *client;
  686. X    struct rmtcallargs a;
  687. X    struct rmtcallres r;
  688. X    enum clnt_stat stat;
  689. X
  690. X    addr->sin_port = htons(PMAPPORT);
  691. X    client = clntudp_create(addr, PMAPPROG, PMAPVERS, timeout, &socket);
  692. X    if (client != (CLIENT *)NULL) {
  693. X        a.prog = prog;
  694. X        a.vers = vers;
  695. X        a.proc = proc;
  696. X        a.args_ptr = argsp;
  697. X        a.xdr_args = xdrargs;
  698. X        r.port_ptr = port_ptr;
  699. X        r.results_ptr = resp;
  700. X        r.xdr_results = xdrres;
  701. X        stat = CLNT_CALL(client, PMAPPROC_CALLIT, xdr_rmtcall_args, &a,
  702. X            xdr_rmtcallres, &r, tout);
  703. X        CLNT_DESTROY(client);
  704. X    } else {
  705. X        stat = RPC_FAILED;
  706. X    }
  707. X    (void)close(socket);
  708. X    addr->sin_port = 0;
  709. X    return (stat);
  710. X}
  711. X
  712. X/*
  713. X * XDR remote call arguments
  714. X * written for XDR_ENCODE direction only
  715. X */
  716. Xstatic bool_t
  717. Xxdr_rmtcall_args(xdrs, cap)
  718. X    register XDR *xdrs;
  719. X    register struct rmtcallargs *cap;
  720. X{
  721. X    u_int lenposition, argposition, position;
  722. X
  723. X    if (xdr_u_long(xdrs, &(cap->prog)) &&
  724. X        xdr_u_long(xdrs, &(cap->vers)) &&
  725. X        xdr_u_long(xdrs, &(cap->proc))) {
  726. X        lenposition = XDR_GETPOS(xdrs);
  727. X        if (! xdr_u_long(xdrs, &(cap->arglen)))
  728. X            return (FALSE);
  729. X        argposition = XDR_GETPOS(xdrs);
  730. X        if (! (*(cap->xdr_args))(xdrs, cap->args_ptr))
  731. X            return (FALSE);
  732. X        position = XDR_GETPOS(xdrs);
  733. X        cap->arglen = (u_long)position - (u_long)argposition;
  734. X        XDR_SETPOS(xdrs, lenposition);
  735. X        if (! xdr_u_long(xdrs, &(cap->arglen)))
  736. X            return (FALSE);
  737. X        XDR_SETPOS(xdrs, position);
  738. X        return (TRUE);
  739. X    }
  740. X    return (FALSE);
  741. X}
  742. X
  743. X/*
  744. X * XDR remote call results
  745. X * written for XDR_DECODE direction only
  746. X */
  747. Xstatic bool_t
  748. Xxdr_rmtcallres(xdrs, crp)
  749. X    register XDR *xdrs;
  750. X    register struct rmtcallres *crp;
  751. X{
  752. X
  753. X    if (xdr_reference(xdrs, &crp->port_ptr, sizeof (u_long), xdr_u_long) &&
  754. X        xdr_u_long(xdrs, &crp->resultslen))
  755. X        return ((*(crp->xdr_results))(xdrs, crp->results_ptr));
  756. X    return (FALSE);
  757. X}
  758. X
  759. X/*
  760. X * The following is kludged-up support for simple rpc broadcasts.
  761. X * Someday a large, complicated system will replace these trivial 
  762. X * routines which only support udp/ip .
  763. X */
  764. X
  765. Xstatic int
  766. Xgetbroadcastnets(addrs, sock, buf)
  767. X    struct in_addr *addrs;
  768. X    int sock;  /* any valid socket will do */
  769. X    char *buf;  /* why allocxate more when we can use existing... */
  770. X{
  771. X    struct ifconf ifc;
  772. X        struct ifreq ifreq, *ifr;
  773. X    struct sockaddr_in *sin;
  774. X        int n, i;
  775. X
  776. X    ifc.ifc_len = MAX_BROADCAST_SIZE;
  777. X        ifc.ifc_buf = buf;
  778. X        if (ioctl(sock, SIOCGIFCONF, (char *)&ifc) < 0) {
  779. X                perror("broadcast: ioctl (get interface configuration)");
  780. X                return (0);
  781. X        }
  782. X        ifr = ifc.ifc_req;
  783. X        for (i = 0, n = ifc.ifc_len/sizeof (struct ifreq); n > 0; n--, ifr++) {
  784. X                ifreq = *ifr;
  785. X                if (ioctl(sock, SIOCGIFFLAGS, (char *)&ifreq) < 0) {
  786. X                        perror("broadcast: ioctl (get interface flags)");
  787. X                        continue;
  788. X                }
  789. X                if ((ifreq.ifr_flags & IFF_BROADCAST) &&
  790. X            (ifreq.ifr_flags & IFF_UP) &&
  791. X            ifr->ifr_addr.sa_family == AF_INET) {
  792. X                        sin = (struct sockaddr_in *)&ifr->ifr_addr;
  793. X            addrs[i++] = inet_makeaddr(inet_netof
  794. X                (sin->sin_addr.s_addr), INADDR_ANY);
  795. X                }
  796. X        }
  797. X    return (i);
  798. X}
  799. X
  800. Xtypedef bool_t (*resultproc_t)();
  801. X
  802. Xenum clnt_stat 
  803. Xclnt_broadcast(prog, vers, proc, xargs, argsp, xresults, resultsp, eachresult)
  804. X    u_long        prog;        /* program number */
  805. X    u_long        vers;        /* version number */
  806. X    u_long        proc;        /* procedure number */
  807. X    xdrproc_t    xargs;        /* xdr routine for args */
  808. X    caddr_t        argsp;        /* pointer to args */
  809. X    xdrproc_t    xresults;    /* xdr routine for results */
  810. X    caddr_t        resultsp;    /* pointer to results */
  811. X    resultproc_t    eachresult;    /* call with each result obtained */
  812. X{
  813. X    enum clnt_stat stat;
  814. X    AUTH *unix_auth = authunix_create_default();
  815. X    XDR xdr_stream;
  816. X    register XDR *xdrs = &xdr_stream;
  817. X    int outlen, inlen, fromlen, readfds, nets;
  818. X    register int sock, mask, i;
  819. X    bool_t done = FALSE;
  820. X    register u_long xid;
  821. X    u_long port;
  822. X    struct in_addr addrs[20];
  823. X    struct sockaddr_in baddr, raddr; /* broadcast and response addresses */
  824. X    struct rmtcallargs a;
  825. X    struct rmtcallres r;
  826. X    struct rpc_msg msg;
  827. X    struct timeval t; 
  828. X    char outbuf[MAX_BROADCAST_SIZE], inbuf[MAX_BROADCAST_SIZE];
  829. X
  830. X    /*
  831. X     * initialization: create a socket, a broadcast address, and
  832. X     * preserialize the arguments into a send buffer.
  833. X     */
  834. X    if ((sock = socket(AF_INET, SOCK_DGRAM, IPPROTO_UDP)) < 0) {
  835. X        perror("Cannot create socket for broadcast rpc");
  836. X        stat = RPC_CANTSEND;
  837. X        goto done_broad;
  838. X    }
  839. X    mask = (1 << sock);
  840. X    nets = getbroadcastnets(addrs, sock, inbuf);
  841. X    bzero(&baddr, sizeof (baddr));
  842. X    baddr.sin_family = AF_INET;
  843. X    baddr.sin_port = htons(PMAPPORT);
  844. X    baddr.sin_addr.S_un.S_addr = htonl(INADDR_ANY);
  845. X    (void)gettimeofday(&t, (struct timezone *)0);
  846. X    msg.rm_xid = xid = getpid() ^ t.tv_sec ^ t.tv_usec;
  847. X    t.tv_usec = 0;
  848. X    msg.rm_direction = CALL;
  849. X    msg.rm_call.cb_rpcvers = RPC_MSG_VERSION;
  850. X    msg.rm_call.cb_prog = PMAPPROG;
  851. X    msg.rm_call.cb_vers = PMAPVERS;
  852. X    msg.rm_call.cb_proc = PMAPPROC_CALLIT;
  853. X    msg.rm_call.cb_cred = unix_auth->ah_cred;
  854. X    msg.rm_call.cb_verf = unix_auth->ah_verf;
  855. X    a.prog = prog;
  856. X    a.vers = vers;
  857. X    a.proc = proc;
  858. X    a.xdr_args = xargs;
  859. X    a.args_ptr = argsp;
  860. X    r.port_ptr = &port;
  861. X    r.xdr_results = xresults;
  862. X    r.results_ptr = resultsp;
  863. X    xdrmem_create(xdrs, outbuf, MAX_BROADCAST_SIZE, XDR_ENCODE);
  864. X    if ((! xdr_callmsg(xdrs, &msg)) || (! xdr_rmtcall_args(xdrs, &a))) {
  865. X        stat = RPC_CANTENCODEARGS;
  866. X        goto done_broad;
  867. X    }
  868. X    outlen = (int)xdr_getpos(xdrs);
  869. X    xdr_destroy(xdrs);
  870. X    /*
  871. X     * Basic loop: broadcast a packet and wait a while for response(s).
  872. X     * The response timeout grows larger per iteration.
  873. X     */
  874. X    for (t.tv_sec = 4; t.tv_sec <= 14; t.tv_sec += 2) {
  875. X        for (i = 0; i < nets; i++) {
  876. X            baddr.sin_addr = addrs[i];
  877. X            if (sendto(sock, outbuf, outlen, 0,
  878. X                (struct socketaddr *)&baddr,
  879. X                sizeof (struct sockaddr)) != outlen) {
  880. X                perror("Cannot send broadcast packet");
  881. X                stat = RPC_CANTSEND;
  882. X                goto done_broad;
  883. X            }
  884. X        }
  885. X    recv_again:
  886. X        msg.acpted_rply.ar_verf = _null_auth;
  887. X        msg.acpted_rply.ar_results.where = (caddr_t)&r;
  888. X                msg.acpted_rply.ar_results.proc = xdr_rmtcallres;
  889. X        readfds = mask;
  890. X        switch (select(32, &readfds, (int *)NULL, (int *)NULL, &t)) {
  891. X
  892. X        case 0:  /* timed out */
  893. X            stat = RPC_TIMEDOUT;
  894. X            continue;
  895. X
  896. X        case -1:  /* some kind of error */
  897. X            if (errno == EINTR)
  898. X                goto recv_again;
  899. X            perror("Broadcast select problem");
  900. X            stat = RPC_CANTRECV;
  901. X            goto done_broad;
  902. X
  903. X        }  /* end of select results switch */
  904. X        if ((readfds & mask) == 0)
  905. X            goto recv_again;
  906. X    try_again:
  907. X        fromlen = sizeof(struct sockaddr);
  908. X        inlen = recvfrom(sock, inbuf, MAX_BROADCAST_SIZE, 0,
  909. X            (struct sockaddr *)&raddr, &fromlen);
  910. X        if (inlen < 0) {
  911. X            if (errno == EINTR)
  912. X                goto try_again;
  913. X            perror("Cannot receive reply to broadcast");
  914. X            stat = RPC_CANTRECV;
  915. X            goto done_broad;
  916. X        }
  917. X        if (inlen < sizeof(u_long))
  918. X            goto recv_again;
  919. X        /*
  920. X         * see if reply transaction id matches sent id.
  921. X         * If so, decode the results.
  922. X         */
  923. X        xdrmem_create(xdrs, inbuf, inlen, XDR_DECODE);
  924. X        if (xdr_replymsg(xdrs, &msg)) {
  925. X            if ((msg.rm_xid == xid) &&
  926. X                (msg.rm_reply.rp_stat == MSG_ACCEPTED) &&
  927. X                (msg.acpted_rply.ar_stat == SUCCESS)) {
  928. X                raddr.sin_port = htons((u_short)port);
  929. X                done = (*eachresult)(resultsp, &raddr);
  930. X            }
  931. X            /* otherwise, we just ignore the errors ... */
  932. X        } else {
  933. X#ifdef notdef
  934. X            /* some kind of deserialization problem ... */
  935. X            if (msg.rm_xid == xid)
  936. X                fprintf(stderr, "Broadcast deserialization problem");
  937. X            /* otherwise, just random garbage */
  938. X#endif
  939. X        }
  940. X        xdrs->x_op = XDR_FREE;
  941. X        msg.acpted_rply.ar_results.proc = xdr_void;
  942. X        (void)xdr_replymsg(xdrs, &msg);
  943. X        (void)(*xresults)(xdrs, resultsp);
  944. X        xdr_destroy(xdrs);
  945. X        if (done) {
  946. X            stat = RPC_SUCCESS;
  947. X            goto done_broad;
  948. X        } else {
  949. X            goto recv_again;
  950. X        }
  951. X    }
  952. Xdone_broad:
  953. X    (void)close(sock);
  954. X    AUTH_DESTROY(unix_auth);
  955. X    return (stat);
  956. X}
  957. SHAR_EOF
  958. if test 10629 -ne "`wc -c < 'rpc/rpclib/pmap_rmt.c'`"
  959. then
  960.     echo shar: "error transmitting 'rpc/rpclib/pmap_rmt.c'" '(should have been 10629 characters)'
  961. fi
  962. chmod 444 'rpc/rpclib/pmap_rmt.c'
  963. fi
  964. echo shar: "extracting 'rpc/rpclib/rpc_prot.c'" '(14335 characters)'
  965. if test -f 'rpc/rpclib/rpc_prot.c'
  966. then
  967.     echo shar: "will not over-write existing file 'rpc/rpclib/rpc_prot.c'"
  968. else
  969. sed 's/^X//' << \SHAR_EOF > 'rpc/rpclib/rpc_prot.c'
  970. X/*
  971. X * Sun RPC is a product of Sun Microsystems, Inc. and is provided for
  972. X * unrestricted use provided that this legend is included on all tape
  973. X * media and as a part of the software program in whole or part.  Users
  974. X * may copy or modify Sun RPC without charge, but are not authorized
  975. X * to license or distribute it to anyone else except as part of a product or
  976. X * program developed by the user.
  977. X * 
  978. X * SUN RPC IS PROVIDED AS IS WITH NO WARRANTIES OF ANY KIND INCLUDING THE
  979. X * WARRANTIES OF DESIGN, MERCHANTIBILITY AND FITNESS FOR A PARTICULAR
  980. X * PURPOSE, OR ARISING FROM A COURSE OF DEALING, USAGE OR TRADE PRACTICE.
  981. X * 
  982. X * Sun RPC is provided with no support and without any obligation on the
  983. X * part of Sun Microsystems, Inc. to assist in its use, correction,
  984. X * modification or enhancement.
  985. X * 
  986. X * SUN MICROSYSTEMS, INC. SHALL HAVE NO LIABILITY WITH RESPECT TO THE
  987. X * INFRINGEMENT OF COPYRIGHTS, TRADE SECRETS OR ANY PATENTS BY SUN RPC
  988. X * OR ANY PART THEREOF.
  989. X * 
  990. X * In no event will Sun Microsystems, Inc. be liable for any lost revenue
  991. X * or profits or other special, indirect and consequential damages, even if
  992. X * Sun has been advised of the possibility of such damages.
  993. X * 
  994. X * Sun Microsystems, Inc.
  995. X * 2550 Garcia Avenue
  996. X * Mountain View, California  94043
  997. X */
  998. X#ifndef lint
  999. Xstatic char sccsid[] = "@(#)rpc_prot.c 1.1 86/02/03 Copyr 1984 Sun Micro";
  1000. X#endif
  1001. X
  1002. X/*
  1003. X * rpc_prot.c
  1004. X *
  1005. X * Copyright (C) 1984, Sun Microsystems, Inc.
  1006. X *
  1007. X * This set of routines implements the rpc message definition,
  1008. X * its serializer and some common rpc utility routines.
  1009. X * The routines are meant for various implementations of rpc -
  1010. X * they are NOT for the rpc client or rpc service implementations!
  1011. X * Because authentication stuff is easy and is part of rpc, the opaque
  1012. X * routines are also in this program.
  1013. X */
  1014. X
  1015. X#include <sys/param.h>
  1016. X#include "types.h"
  1017. X#include "xdr.h"
  1018. X#include "auth.h"
  1019. X#include "clnt.h"
  1020. X#include "rpc_msg.h"
  1021. X#include <netinet/in.h>
  1022. X
  1023. X/* * * * * * * * * * * * * * XDR Authentication * * * * * * * * * * * */
  1024. X
  1025. Xstruct opaque_auth _null_auth;
  1026. X
  1027. X/*
  1028. X * XDR an opaque authentication struct
  1029. X * (see auth.h)
  1030. X */
  1031. Xbool_t
  1032. Xxdr_opaque_auth(xdrs, ap)
  1033. X    register XDR *xdrs;
  1034. X    register struct opaque_auth *ap;
  1035. X{
  1036. X
  1037. X    if (xdr_enum(xdrs, &(ap->oa_flavor)))
  1038. X        return (xdr_bytes(xdrs, &ap->oa_base,
  1039. X            &ap->oa_length, MAX_AUTH_BYTES));
  1040. X    return (FALSE);
  1041. X}
  1042. X
  1043. X/*
  1044. X * XDR a DES key.
  1045. X */
  1046. Xbool_t
  1047. Xxdr_deskey(xdrs, blkp)
  1048. X    register XDR *xdrs;
  1049. X    register union des_block *blkp;
  1050. X{
  1051. X
  1052. X    if (! xdr_u_long(xdrs, &(blkp->key.high)))
  1053. X        return (FALSE);
  1054. X    return (xdr_u_long(xdrs, &(blkp->key.low)));
  1055. X}
  1056. X
  1057. X/* * * * * * * * * * * * * * XDR RPC MESSAGE * * * * * * * * * * * * * * * */
  1058. X
  1059. X/*
  1060. X * XDR the MSG_ACCEPTED part of a reply message union
  1061. X */
  1062. Xbool_t 
  1063. Xxdr_accepted_reply(xdrs, ar)
  1064. X    register XDR *xdrs;   
  1065. X    register struct accepted_reply *ar;
  1066. X{
  1067. X
  1068. X    /* personalized union, rather than calling xdr_union */
  1069. X    if (! xdr_opaque_auth(xdrs, &(ar->ar_verf)))
  1070. X        return (FALSE);
  1071. X    if (! xdr_enum(xdrs, (enum_t *)&(ar->ar_stat)))
  1072. X        return (FALSE);
  1073. X    switch (ar->ar_stat) {
  1074. X
  1075. X    case SUCCESS:
  1076. X        return ((*(ar->ar_results.proc))(xdrs, ar->ar_results.where));
  1077. X    
  1078. X    case PROG_MISMATCH:
  1079. X        if (! xdr_u_long(xdrs, &(ar->ar_vers.low)))
  1080. X            return (FALSE);
  1081. X        return (xdr_u_long(xdrs, &(ar->ar_vers.high)));
  1082. X    }
  1083. X    return (TRUE);  /* TRUE => open ended set of problems */
  1084. X}
  1085. X
  1086. X/*
  1087. X * XDR the MSG_DENIED part of a reply message union
  1088. X */
  1089. Xbool_t 
  1090. Xxdr_rejected_reply(xdrs, rr)
  1091. X    register XDR *xdrs;
  1092. X    register struct rejected_reply *rr;
  1093. X{
  1094. X
  1095. X    /* personalized union, rather than calling xdr_union */
  1096. X    if (! xdr_enum(xdrs, (enum_t *)&(rr->rj_stat)))
  1097. X        return (FALSE);
  1098. X    switch (rr->rj_stat) {
  1099. X
  1100. X    case RPC_MISMATCH:
  1101. X        if (! xdr_u_long(xdrs, &(rr->rj_vers.low)))
  1102. X            return (FALSE);
  1103. X        return (xdr_u_long(xdrs, &(rr->rj_vers.high)));
  1104. X
  1105. X    case AUTH_ERROR:
  1106. X        return (xdr_enum(xdrs, (enum_t *)&(rr->rj_why)));
  1107. X    }
  1108. X    return (FALSE);
  1109. X}
  1110. X
  1111. X#define    RNDUP(x)  ((((x) + BYTES_PER_XDR_UNIT - 1) / BYTES_PER_XDR_UNIT) \
  1112. X           * BYTES_PER_XDR_UNIT)
  1113. X
  1114. Xstatic struct xdr_discrim reply_dscrm[3] = {
  1115. X    { (int)MSG_ACCEPTED, xdr_accepted_reply },
  1116. X    { (int)MSG_DENIED, xdr_rejected_reply },
  1117. X    { __dontcare__, NULL_xdrproc_t } };
  1118. X
  1119. X/*
  1120. X * XDR a reply message
  1121. X */
  1122. Xbool_t
  1123. Xxdr_replymsg(xdrs, rmsg)
  1124. X    register XDR *xdrs;
  1125. X    register struct rpc_msg *rmsg;
  1126. X{
  1127. X    register long *buf;
  1128. X    register struct accepted_reply *ar;
  1129. X    register struct opaque_auth *oa;
  1130. X
  1131. X    if (xdrs->x_op == XDR_ENCODE &&
  1132. X        rmsg->rm_reply.rp_stat == MSG_ACCEPTED &&
  1133. X        rmsg->rm_direction == REPLY &&
  1134. X        (buf = XDR_INLINE(xdrs, 6 * BYTES_PER_XDR_UNIT +
  1135. X        rmsg->rm_reply.rp_acpt.ar_verf.oa_length)) != NULL) {
  1136. X        IXDR_PUT_LONG(buf, rmsg->rm_xid);
  1137. X        IXDR_PUT_ENUM(buf, rmsg->rm_direction);
  1138. X        IXDR_PUT_ENUM(buf, rmsg->rm_reply.rp_stat);
  1139. X        ar = &rmsg->rm_reply.rp_acpt;
  1140. X        oa = &ar->ar_verf;
  1141. X        IXDR_PUT_ENUM(buf, oa->oa_flavor);
  1142. X        IXDR_PUT_LONG(buf, oa->oa_length);
  1143. X        if (oa->oa_length) {
  1144. X            bcopy(oa->oa_base, buf, oa->oa_length);
  1145. X            buf += (oa->oa_length +
  1146. X                BYTES_PER_XDR_UNIT - 1) /
  1147. X                sizeof (long);
  1148. X        }
  1149. X        /*
  1150. X         * stat and rest of reply, copied from xdr_accepted_reply
  1151. X         */
  1152. X        IXDR_PUT_ENUM(buf, ar->ar_stat);
  1153. X        switch (ar->ar_stat) {
  1154. X
  1155. X        case SUCCESS:
  1156. X            return ((*(ar->ar_results.proc))
  1157. X                (xdrs, ar->ar_results.where));
  1158. X    
  1159. X        case PROG_MISMATCH:
  1160. X            if (! xdr_u_long(xdrs, &(ar->ar_vers.low)))
  1161. X                return (FALSE);
  1162. X            return (xdr_u_long(xdrs, &(ar->ar_vers.high)));
  1163. X        }
  1164. X        return (TRUE);
  1165. X    }
  1166. X    if (xdrs->x_op == XDR_DECODE &&
  1167. X        (buf = XDR_INLINE(xdrs, 3 * BYTES_PER_XDR_UNIT)) != NULL) {
  1168. X        rmsg->rm_xid = IXDR_GET_LONG(buf);
  1169. X        rmsg->rm_direction = IXDR_GET_ENUM(buf, enum msg_type);
  1170. X        if (rmsg->rm_direction != REPLY) {
  1171. X            return (FALSE);
  1172. X        }
  1173. X        rmsg->rm_reply.rp_stat = IXDR_GET_ENUM(buf, enum reply_stat);
  1174. X        if (rmsg->rm_reply.rp_stat != MSG_ACCEPTED) {
  1175. X            if (rmsg->rm_reply.rp_stat == MSG_DENIED) {
  1176. X                return (xdr_rejected_reply(xdrs,
  1177. X                    &rmsg->rm_reply.rp_rjct));
  1178. X            }
  1179. X            return (FALSE);
  1180. X        }
  1181. X        ar = &rmsg->rm_reply.rp_acpt;
  1182. X        oa = &ar->ar_verf;
  1183. X        buf = XDR_INLINE(xdrs, 2 * BYTES_PER_XDR_UNIT);
  1184. X        if (buf != NULL) {
  1185. X            oa->oa_flavor = IXDR_GET_ENUM(buf, enum_t);
  1186. X            oa->oa_length = IXDR_GET_LONG(buf);
  1187. X        } else {
  1188. X            if (xdr_enum(xdrs, &oa->oa_flavor) == FALSE ||
  1189. X                xdr_u_int(xdrs, &oa->oa_length) == FALSE) {
  1190. X                return (FALSE);
  1191. X            }
  1192. X        }
  1193. X        if (oa->oa_length) {
  1194. X            if (oa->oa_length > MAX_AUTH_BYTES) {
  1195. X                return (FALSE);
  1196. X            }
  1197. X            if (oa->oa_base == NULL) {
  1198. X                oa->oa_base = (caddr_t)
  1199. X                    mem_alloc(oa->oa_length);
  1200. X            }
  1201. X            buf = XDR_INLINE(xdrs, RNDUP(oa->oa_length));
  1202. X            if (buf == NULL) {
  1203. X                if (xdr_opaque(xdrs, oa->oa_base,
  1204. X                    oa->oa_length) == FALSE) {
  1205. X                    return (FALSE);
  1206. X                }
  1207. X            } else {
  1208. X                bcopy(buf, oa->oa_base, oa->oa_length);
  1209. X                /* no real need....
  1210. X                buf += RNDUP(oa->oa_length) / sizeof (long);
  1211. X                */
  1212. X            }
  1213. X        }
  1214. X        /*
  1215. X         * stat and rest of reply, copied from
  1216. X         * xdr_accepted_reply
  1217. X         */
  1218. X        xdr_enum(xdrs, &ar->ar_stat);
  1219. X        switch (ar->ar_stat) {
  1220. X
  1221. X        case SUCCESS:
  1222. X            return ((*(ar->ar_results.proc))
  1223. X                (xdrs, ar->ar_results.where));
  1224. X
  1225. X        case PROG_MISMATCH:
  1226. X            if (! xdr_u_long(xdrs, &(ar->ar_vers.low)))
  1227. X                return (FALSE);
  1228. X            return (xdr_u_long(xdrs, &(ar->ar_vers.high)));
  1229. X        }
  1230. X        return (TRUE);
  1231. X    }
  1232. X    if (
  1233. X        xdr_u_long(xdrs, &(rmsg->rm_xid)) && 
  1234. X        xdr_enum(xdrs, (enum_t *)&(rmsg->rm_direction)) &&
  1235. X        (rmsg->rm_direction == REPLY) )
  1236. X        return (xdr_union(xdrs, (enum_t *)&(rmsg->rm_reply.rp_stat),
  1237. X            (caddr_t)&(rmsg->rm_reply.ru), reply_dscrm, NULL_xdrproc_t));
  1238. X    return (FALSE);
  1239. X}
  1240. X
  1241. X/*
  1242. X * XDR a call message
  1243. X */
  1244. Xbool_t
  1245. Xxdr_callmsg(xdrs, cmsg)
  1246. X    register XDR *xdrs;
  1247. X    register struct rpc_msg *cmsg;
  1248. X{
  1249. X    register long *buf;
  1250. X    register struct opaque_auth *oa;
  1251. X
  1252. X    if (xdrs->x_op == XDR_ENCODE) {
  1253. X        if (cmsg->rm_call.cb_cred.oa_length > MAX_AUTH_BYTES) {
  1254. X            return (FALSE);
  1255. X        }
  1256. X        if (cmsg->rm_call.cb_verf.oa_length > MAX_AUTH_BYTES) {
  1257. X            return (FALSE);
  1258. X        }
  1259. X        buf = XDR_INLINE(xdrs, 8 * BYTES_PER_XDR_UNIT
  1260. X            + RNDUP(cmsg->rm_call.cb_cred.oa_length)
  1261. X            + 2 * BYTES_PER_XDR_UNIT
  1262. X            + RNDUP(cmsg->rm_call.cb_verf.oa_length));
  1263. X        if (buf != NULL) {
  1264. X            IXDR_PUT_LONG(buf, cmsg->rm_xid);
  1265. X            IXDR_PUT_ENUM(buf, cmsg->rm_direction);
  1266. X            if (cmsg->rm_direction != CALL) {
  1267. X                return (FALSE);
  1268. X            }
  1269. X            IXDR_PUT_LONG(buf, cmsg->rm_call.cb_rpcvers);
  1270. X            if (cmsg->rm_call.cb_rpcvers != RPC_MSG_VERSION) {
  1271. X                return (FALSE);
  1272. X            }
  1273. X            IXDR_PUT_LONG(buf, cmsg->rm_call.cb_prog);
  1274. X            IXDR_PUT_LONG(buf, cmsg->rm_call.cb_vers);
  1275. X            IXDR_PUT_LONG(buf, cmsg->rm_call.cb_proc);
  1276. X            oa = &cmsg->rm_call.cb_cred;
  1277. X            IXDR_PUT_ENUM(buf, oa->oa_flavor);
  1278. X            IXDR_PUT_LONG(buf, oa->oa_length);
  1279. X            if (oa->oa_length) {
  1280. X                bcopy(oa->oa_base, buf, oa->oa_length);
  1281. X                buf += RNDUP(oa->oa_length) / sizeof (long);
  1282. X            }
  1283. X            oa = &cmsg->rm_call.cb_verf;
  1284. X            IXDR_PUT_ENUM(buf, oa->oa_flavor);
  1285. X            IXDR_PUT_LONG(buf, oa->oa_length);
  1286. X            if (oa->oa_length) {
  1287. X                bcopy(oa->oa_base, buf, oa->oa_length);
  1288. X                /* no real need....
  1289. X                buf += RNDUP(oa->oa_length) / sizeof (long);
  1290. X                */
  1291. X            }
  1292. X            return (TRUE);
  1293. X        }
  1294. X    }
  1295. X    if (xdrs->x_op == XDR_DECODE) {
  1296. X        buf = XDR_INLINE(xdrs, 8 * BYTES_PER_XDR_UNIT);
  1297. X        if (buf != NULL) {
  1298. X            cmsg->rm_xid = IXDR_GET_LONG(buf);
  1299. X            cmsg->rm_direction = IXDR_GET_ENUM(buf, enum msg_type);
  1300. X            if (cmsg->rm_direction != CALL) {
  1301. X                return (FALSE);
  1302. X            }
  1303. X            cmsg->rm_call.cb_rpcvers = IXDR_GET_LONG(buf);
  1304. X            if (cmsg->rm_call.cb_rpcvers != RPC_MSG_VERSION) {
  1305. X                return (FALSE);
  1306. X            }
  1307. X            cmsg->rm_call.cb_prog = IXDR_GET_LONG(buf);
  1308. X            cmsg->rm_call.cb_vers = IXDR_GET_LONG(buf);
  1309. X            cmsg->rm_call.cb_proc = IXDR_GET_LONG(buf);
  1310. X            oa = &cmsg->rm_call.cb_cred;
  1311. X            oa->oa_flavor = IXDR_GET_ENUM(buf, enum_t);
  1312. X            oa->oa_length = IXDR_GET_LONG(buf);
  1313. X            if (oa->oa_length) {
  1314. X                if (oa->oa_length > MAX_AUTH_BYTES) {
  1315. X                    return (FALSE);
  1316. X                }
  1317. X                if (oa->oa_base == NULL) {
  1318. X                    oa->oa_base = (caddr_t)
  1319. X                        mem_alloc(oa->oa_length);
  1320. X                }
  1321. X                buf = XDR_INLINE(xdrs, RNDUP(oa->oa_length));
  1322. X                if (buf == NULL) {
  1323. X                    if (xdr_opaque(xdrs, oa->oa_base,
  1324. X                        oa->oa_length) == FALSE) {
  1325. X                        return (FALSE);
  1326. X                    }
  1327. X                } else {
  1328. X                    bcopy(buf, oa->oa_base, oa->oa_length);
  1329. X                    /* no real need....
  1330. X                    buf += RNDUP(oa->oa_length) /
  1331. X                        sizeof (long);
  1332. X                    */
  1333. X                }
  1334. X            }
  1335. X            oa = &cmsg->rm_call.cb_verf;
  1336. X            buf = XDR_INLINE(xdrs, 2 * BYTES_PER_XDR_UNIT);
  1337. X            if (buf == NULL) {
  1338. X                if (xdr_enum(xdrs, &oa->oa_flavor) == FALSE ||
  1339. X                    xdr_u_int(xdrs, &oa->oa_length) == FALSE) {
  1340. X                    return (FALSE);
  1341. X                }
  1342. X            } else {
  1343. X                oa->oa_flavor = IXDR_GET_ENUM(buf, enum_t);
  1344. X                oa->oa_length = IXDR_GET_LONG(buf);
  1345. X            }
  1346. X            if (oa->oa_length) {
  1347. X                if (oa->oa_length > MAX_AUTH_BYTES) {
  1348. X                    return (FALSE);
  1349. X                }
  1350. X                if (oa->oa_base == NULL) {
  1351. X                    oa->oa_base = (caddr_t)
  1352. X                        mem_alloc(oa->oa_length);
  1353. X                }
  1354. X                buf = XDR_INLINE(xdrs, RNDUP(oa->oa_length));
  1355. X                if (buf == NULL) {
  1356. X                    if (xdr_opaque(xdrs, oa->oa_base,
  1357. X                        oa->oa_length) == FALSE) {
  1358. X                        return (FALSE);
  1359. X                    }
  1360. X                } else {
  1361. X                    bcopy(buf, oa->oa_base, oa->oa_length);
  1362. X                    /* no real need...
  1363. X                    buf += RNDUP(oa->oa_length) /
  1364. X                        sizeof (long);
  1365. X                    */
  1366. X                }
  1367. X            }
  1368. X            return (TRUE);
  1369. X        }
  1370. X    }
  1371. X    if (
  1372. X        xdr_u_long(xdrs, &(cmsg->rm_xid)) &&
  1373. X        xdr_enum(xdrs, (enum_t *)&(cmsg->rm_direction)) &&
  1374. X        (cmsg->rm_direction == CALL) &&
  1375. X        xdr_u_long(xdrs, &(cmsg->rm_call.cb_rpcvers)) &&
  1376. X        (cmsg->rm_call.cb_rpcvers == RPC_MSG_VERSION) &&
  1377. X        xdr_u_long(xdrs, &(cmsg->rm_call.cb_prog)) &&
  1378. X        xdr_u_long(xdrs, &(cmsg->rm_call.cb_vers)) &&
  1379. X        xdr_u_long(xdrs, &(cmsg->rm_call.cb_proc)) &&
  1380. X        xdr_opaque_auth(xdrs, &(cmsg->rm_call.cb_cred)) )
  1381. X        return (xdr_opaque_auth(xdrs, &(cmsg->rm_call.cb_verf)));
  1382. X    return (FALSE);
  1383. X}
  1384. X
  1385. X/*
  1386. X * Serializes the "static part" of a call message header.
  1387. X * The fields include: rm_xid, rm_direction, rpcvers, prog, and vers.
  1388. X * The rm_xid is not really static, but the user can easily munge on the fly.
  1389. X */
  1390. Xbool_t
  1391. Xxdr_callhdr(xdrs, cmsg)
  1392. X    register XDR *xdrs;
  1393. X    register struct rpc_msg *cmsg;
  1394. X{
  1395. X
  1396. X    cmsg->rm_direction = CALL;
  1397. X    cmsg->rm_call.cb_rpcvers = RPC_MSG_VERSION;
  1398. X    if (
  1399. X        (xdrs->x_op == XDR_ENCODE) &&
  1400. X        xdr_u_long(xdrs, &(cmsg->rm_xid)) &&
  1401. X        xdr_enum(xdrs, (enum_t *)&(cmsg->rm_direction)) &&
  1402. X        xdr_u_long(xdrs, &(cmsg->rm_call.cb_rpcvers)) &&
  1403. X        xdr_u_long(xdrs, &(cmsg->rm_call.cb_prog)) )
  1404. X        return (xdr_u_long(xdrs, &(cmsg->rm_call.cb_vers)));
  1405. X    return (FALSE);
  1406. X}
  1407. X
  1408. X/* ************************** Client utility routine ************* */
  1409. X
  1410. Xstatic void
  1411. Xaccepted(acpt_stat, error)
  1412. X    register enum accept_stat acpt_stat;
  1413. X    register struct rpc_err *error;
  1414. X{
  1415. X
  1416. X    switch (acpt_stat) {
  1417. X
  1418. X    case PROG_UNAVAIL:
  1419. X        error->re_status = RPC_PROGUNAVAIL;
  1420. X        return;
  1421. X
  1422. X    case PROG_MISMATCH:
  1423. X        error->re_status = RPC_PROGVERSMISMATCH;
  1424. X        return;
  1425. X
  1426. X    case PROC_UNAVAIL:
  1427. X        error->re_status = RPC_PROCUNAVAIL;
  1428. X        return;
  1429. X
  1430. X    case GARBAGE_ARGS:
  1431. X        error->re_status = RPC_CANTDECODEARGS;
  1432. X        return;
  1433. X
  1434. X    case SYSTEM_ERR:
  1435. X        error->re_status = RPC_SYSTEMERROR;
  1436. X        return;
  1437. X
  1438. X    case SUCCESS:
  1439. X        error->re_status = RPC_SUCCESS;
  1440. X        return;
  1441. X    }
  1442. X    /* something's wrong, but we don't know what ... */
  1443. X    error->re_status = RPC_FAILED;
  1444. X    error->re_lb.s1 = (long)MSG_ACCEPTED;
  1445. X    error->re_lb.s2 = (long)acpt_stat;
  1446. X}
  1447. X
  1448. Xstatic void 
  1449. Xrejected(rjct_stat, error)
  1450. X    register enum reject_stat rjct_stat;
  1451. X    register struct rpc_err *error;
  1452. X{
  1453. X
  1454. X    switch (rjct_stat) {
  1455. X
  1456. X    case RPC_VERSMISMATCH:
  1457. X        error->re_status = RPC_VERSMISMATCH;
  1458. X        return;
  1459. X
  1460. X    case AUTH_ERROR:
  1461. X        error->re_status = RPC_AUTHERROR;
  1462. X        return;
  1463. X    }
  1464. X    /* something's wrong, but we don't know what ... */
  1465. X    error->re_status = RPC_FAILED;
  1466. X    error->re_lb.s1 = (long)MSG_DENIED;
  1467. X    error->re_lb.s2 = (long)rjct_stat;
  1468. X}
  1469. X
  1470. X/*
  1471. X * given a reply message, fills in the error
  1472. X */
  1473. Xvoid
  1474. X_seterr_reply(msg, error)
  1475. X    register struct rpc_msg *msg;
  1476. X    register struct rpc_err *error;
  1477. X{
  1478. X
  1479. X    /* optimized for normal, SUCCESSful case */
  1480. X    switch (msg->rm_reply.rp_stat) {
  1481. X
  1482. X    case MSG_ACCEPTED:
  1483. X        if (msg->acpted_rply.ar_stat == SUCCESS) {
  1484. X            error->re_status = RPC_SUCCESS;
  1485. X            return;
  1486. X        };
  1487. X        accepted(msg->acpted_rply.ar_stat, error);
  1488. X        break;
  1489. X
  1490. X    case MSG_DENIED:
  1491. X        rejected(msg->rjcted_rply.rj_stat, error);
  1492. X        break;
  1493. X
  1494. X    default:
  1495. X        error->re_status = RPC_FAILED;
  1496. X        error->re_lb.s1 = (long)(msg->rm_reply.rp_stat);
  1497. X        break;
  1498. X    }
  1499. X    switch (error->re_status) {
  1500. X
  1501. X    case RPC_VERSMISMATCH:
  1502. X        error->re_vers.low = msg->rjcted_rply.rj_vers.low;
  1503. X        error->re_vers.high = msg->rjcted_rply.rj_vers.high;
  1504. X        break;
  1505. X
  1506. X    case RPC_AUTHERROR:
  1507. X        error->re_why = msg->rjcted_rply.rj_why;
  1508. X        break;
  1509. X
  1510. X    case RPC_PROGVERSMISMATCH:
  1511. X        error->re_vers.low = msg->acpted_rply.ar_vers.low;
  1512. X        error->re_vers.high = msg->acpted_rply.ar_vers.high;
  1513. X        break;
  1514. X    }
  1515. X}
  1516. SHAR_EOF
  1517. if test 14335 -ne "`wc -c < 'rpc/rpclib/rpc_prot.c'`"
  1518. then
  1519.     echo shar: "error transmitting 'rpc/rpclib/rpc_prot.c'" '(should have been 14335 characters)'
  1520. fi
  1521. chmod 444 'rpc/rpclib/rpc_prot.c'
  1522. fi
  1523. echo shar: "extracting 'rpc/rpclib/svc.c'" '(10663 characters)'
  1524. if test -f 'rpc/rpclib/svc.c'
  1525. then
  1526.     echo shar: "will not over-write existing file 'rpc/rpclib/svc.c'"
  1527. else
  1528. sed 's/^X//' << \SHAR_EOF > 'rpc/rpclib/svc.c'
  1529. X/*
  1530. X * Sun RPC is a product of Sun Microsystems, Inc. and is provided for
  1531. X * unrestricted use provided that this legend is included on all tape
  1532. X * media and as a part of the software program in whole or part.  Users
  1533. X * may copy or modify Sun RPC without charge, but are not authorized
  1534. X * to license or distribute it to anyone else except as part of a product or
  1535. X * program developed by the user.
  1536. X * 
  1537. X * SUN RPC IS PROVIDED AS IS WITH NO WARRANTIES OF ANY KIND INCLUDING THE
  1538. X * WARRANTIES OF DESIGN, MERCHANTIBILITY AND FITNESS FOR A PARTICULAR
  1539. X * PURPOSE, OR ARISING FROM A COURSE OF DEALING, USAGE OR TRADE PRACTICE.
  1540. X * 
  1541. X * Sun RPC is provided with no support and without any obligation on the
  1542. X * part of Sun Microsystems, Inc. to assist in its use, correction,
  1543. X * modification or enhancement.
  1544. X * 
  1545. X * SUN MICROSYSTEMS, INC. SHALL HAVE NO LIABILITY WITH RESPECT TO THE
  1546. X * INFRINGEMENT OF COPYRIGHTS, TRADE SECRETS OR ANY PATENTS BY SUN RPC
  1547. X * OR ANY PART THEREOF.
  1548. X * 
  1549. X * In no event will Sun Microsystems, Inc. be liable for any lost revenue
  1550. X * or profits or other special, indirect and consequential damages, even if
  1551. X * Sun has been advised of the possibility of such damages.
  1552. X * 
  1553. X * Sun Microsystems, Inc.
  1554. X * 2550 Garcia Avenue
  1555. X * Mountain View, California  94043
  1556. X */
  1557. X#ifndef lint
  1558. Xstatic char sccsid[] = "@(#)svc.c 1.1 86/02/03 Copyr 1984 Sun Micro";
  1559. X#endif
  1560. X
  1561. X/*
  1562. X * svc.c, Server-side remote procedure call interface.
  1563. X *
  1564. X * There are two sets of procedures here.  The xprt routines are
  1565. X * for handling transport handles.  The svc routines handle the
  1566. X * list of service routines.
  1567. X *
  1568. X * Copyright (C) 1984, Sun Microsystems, Inc.
  1569. X */
  1570. X
  1571. X#include "types.h"
  1572. X#include <sys/errno.h>
  1573. X#include <sys/time.h>
  1574. X#include <netinet/in.h>
  1575. X#include "xdr.h"
  1576. X#include "auth.h"
  1577. X#include "clnt.h"
  1578. X#include "rpc_msg.h"
  1579. X#include "svc.h"
  1580. X#include "svc_auth.h"
  1581. X#include "pmap_clnt.h"
  1582. X
  1583. X#define NOFILE 32
  1584. X
  1585. Xstatic SVCXPRT *xports[NOFILE];
  1586. Xint svc_fds;
  1587. Xextern errno;
  1588. Xchar *malloc();
  1589. X
  1590. X#define NULL_SVC ((struct svc_callout *)0)
  1591. X#define    RQCRED_SIZE    400
  1592. X
  1593. X/*
  1594. X * The services list
  1595. X * Each entry represents a set of procedures (an rpc program).
  1596. X * The dispatch routine takes request structs and runs the
  1597. X * apropriate procedure.
  1598. X */
  1599. Xstatic struct svc_callout {
  1600. X    struct svc_callout *sc_next;
  1601. X    u_long            sc_prog;
  1602. X    u_long            sc_vers;
  1603. X    void            (*sc_dispatch)();
  1604. X} *svc_head;
  1605. X
  1606. Xstatic struct svc_callout *svc_find();
  1607. X
  1608. X/* ***************  SVCXPRT related stuff **************** */
  1609. X
  1610. X/*
  1611. X * Activate a transport handle.
  1612. X */
  1613. Xvoid
  1614. Xxprt_register(xprt)
  1615. X    SVCXPRT *xprt;
  1616. X{
  1617. X    register int sock = xprt->xp_sock;
  1618. X
  1619. X    if (sock < NOFILE) {
  1620. X        xports[sock] = xprt;
  1621. X        svc_fds |= (1 << sock);
  1622. X    }
  1623. X}
  1624. X
  1625. X/*
  1626. X * De-activate a transport handle. 
  1627. X */
  1628. Xvoid
  1629. Xxprt_unregister(xprt) 
  1630. X    SVCXPRT *xprt;
  1631. X{ 
  1632. X    register int sock = xprt->xp_sock;
  1633. X
  1634. X    if ((sock < NOFILE) && (xports[sock] == xprt)) {
  1635. X        xports[sock] = (SVCXPRT *)0;
  1636. X        svc_fds &= ~(1 << sock);
  1637. X    }
  1638. X} 
  1639. X
  1640. X
  1641. X/* ********************** CALLOUT list related stuff ************* */
  1642. X
  1643. X/*
  1644. X * Add a service program to the callout list.
  1645. X * The dispatch routine will be called when a rpc request for this
  1646. X * program number comes in.
  1647. X */
  1648. Xbool_t
  1649. Xsvc_register(xprt, prog, vers, dispatch, protocol)
  1650. X    SVCXPRT *xprt;
  1651. X    u_long prog;
  1652. X    u_long vers;
  1653. X    void (*dispatch)();
  1654. X    int protocol;
  1655. X{
  1656. X    struct svc_callout *prev;
  1657. X    register struct svc_callout *s;
  1658. X
  1659. X    if ((s = svc_find(prog, vers, &prev)) != NULL_SVC) {
  1660. X        if (s->sc_dispatch == dispatch)
  1661. X            goto pmap_it;  /* he is registering another xptr */
  1662. X        return (FALSE);
  1663. X    }
  1664. X    s = (struct svc_callout *)mem_alloc(sizeof(struct svc_callout));
  1665. X    if (s == (struct svc_callout *)0) {
  1666. X        return (FALSE);
  1667. X    }
  1668. X    s->sc_prog = prog;
  1669. X    s->sc_vers = vers;
  1670. X    s->sc_dispatch = dispatch;
  1671. X    s->sc_next = svc_head;
  1672. X    svc_head = s;
  1673. Xpmap_it:
  1674. X    /* now register the information with the local binder service */
  1675. X    if (protocol) {
  1676. X        return (pmap_set(prog, vers, protocol, xprt->xp_port));
  1677. X    }
  1678. X    return (TRUE);
  1679. X}
  1680. X
  1681. X/*
  1682. X * Remove a service program from the callout list.
  1683. X */
  1684. Xvoid
  1685. Xsvc_unregister(prog, vers)
  1686. X    u_long prog;
  1687. X    u_long vers;
  1688. X{
  1689. X    struct svc_callout *prev;
  1690. X    register struct svc_callout *s;
  1691. X
  1692. X    if ((s = svc_find(prog, vers, &prev)) == NULL_SVC)
  1693. X        return;
  1694. X    if (prev == NULL_SVC) {
  1695. X        svc_head = s->sc_next;
  1696. X    } else {
  1697. X        prev->sc_next = s->sc_next;
  1698. X    }
  1699. X    s->sc_next = NULL_SVC;
  1700. X    mem_free((char *) s, (u_int) sizeof(struct svc_callout));
  1701. X    /* now unregister the information with the local binder service */
  1702. X    (void)pmap_unset(prog, vers);
  1703. X}
  1704. X
  1705. X/*
  1706. X * Search the callout list for a program number, return the callout
  1707. X * struct.
  1708. X */
  1709. Xstatic struct svc_callout *
  1710. Xsvc_find(prog, vers, prev)
  1711. X    u_long prog;
  1712. X    u_long vers;
  1713. X    struct svc_callout **prev;
  1714. X{
  1715. X    register struct svc_callout *s, *p;
  1716. X
  1717. X    p = NULL_SVC;
  1718. X    for (s = svc_head; s != NULL_SVC; s = s->sc_next) {
  1719. X        if ((s->sc_prog == prog) && (s->sc_vers == vers))
  1720. X            goto done;
  1721. X        p = s;
  1722. X    }
  1723. Xdone:
  1724. X    *prev = p;
  1725. X    return (s);
  1726. X}
  1727. X
  1728. X/* ******************* REPLY GENERATION ROUTINES  ************ */
  1729. X
  1730. X/*
  1731. X * Send a reply to an rpc request
  1732. X */
  1733. Xbool_t
  1734. Xsvc_sendreply(xprt, xdr_results, xdr_location)
  1735. X    register SVCXPRT *xprt;
  1736. X    xdrproc_t xdr_results;
  1737. X    caddr_t xdr_location;
  1738. X{
  1739. X    struct rpc_msg rply; 
  1740. X
  1741. X    rply.rm_direction = REPLY;  
  1742. X    rply.rm_reply.rp_stat = MSG_ACCEPTED; 
  1743. X    rply.acpted_rply.ar_verf = xprt->xp_verf; 
  1744. X    rply.acpted_rply.ar_stat = SUCCESS;
  1745. X    rply.acpted_rply.ar_results.where = xdr_location;
  1746. X    rply.acpted_rply.ar_results.proc = xdr_results;
  1747. X    return (SVC_REPLY(xprt, &rply)); 
  1748. X}
  1749. X
  1750. X/*
  1751. X * No procedure error reply
  1752. X */
  1753. Xvoid
  1754. Xsvcerr_noproc(xprt)
  1755. X    register SVCXPRT *xprt;
  1756. X{
  1757. X    struct rpc_msg rply;
  1758. X
  1759. X    rply.rm_direction = REPLY;
  1760. X    rply.rm_reply.rp_stat = MSG_ACCEPTED;
  1761. X    rply.acpted_rply.ar_verf = xprt->xp_verf;
  1762. X    rply.acpted_rply.ar_stat = PROC_UNAVAIL;
  1763. X    SVC_REPLY(xprt, &rply);
  1764. X}
  1765. X
  1766. X/*
  1767. X * Can't decode args error reply
  1768. X */
  1769. Xvoid
  1770. Xsvcerr_decode(xprt)
  1771. X    register SVCXPRT *xprt;
  1772. X{
  1773. X    struct rpc_msg rply; 
  1774. X
  1775. X    rply.rm_direction = REPLY; 
  1776. X    rply.rm_reply.rp_stat = MSG_ACCEPTED; 
  1777. X    rply.acpted_rply.ar_verf = xprt->xp_verf;
  1778. X    rply.acpted_rply.ar_stat = GARBAGE_ARGS;
  1779. X    SVC_REPLY(xprt, &rply); 
  1780. X}
  1781. X
  1782. X/*
  1783. X * Some system error
  1784. X */
  1785. Xvoid
  1786. Xsvcerr_systemerr(xprt)
  1787. X    register SVCXPRT *xprt;
  1788. X{
  1789. X    struct rpc_msg rply; 
  1790. X
  1791. X    rply.rm_direction = REPLY; 
  1792. X    rply.rm_reply.rp_stat = MSG_ACCEPTED; 
  1793. X    rply.acpted_rply.ar_verf = xprt->xp_verf;
  1794. X    rply.acpted_rply.ar_stat = SYSTEM_ERR;
  1795. X    SVC_REPLY(xprt, &rply); 
  1796. X}
  1797. X
  1798. X/*
  1799. X * Authentication error reply
  1800. X */
  1801. Xvoid
  1802. Xsvcerr_auth(xprt, why)
  1803. X    SVCXPRT *xprt;
  1804. X    enum auth_stat why;
  1805. X{
  1806. X    struct rpc_msg rply;
  1807. X
  1808. X    rply.rm_direction = REPLY;
  1809. X    rply.rm_reply.rp_stat = MSG_DENIED;
  1810. X    rply.rjcted_rply.rj_stat = AUTH_ERROR;
  1811. X    rply.rjcted_rply.rj_why = why;
  1812. X    SVC_REPLY(xprt, &rply);
  1813. X}
  1814. X
  1815. X/*
  1816. X * Auth too weak error reply
  1817. X */
  1818. Xvoid
  1819. Xsvcerr_weakauth(xprt)
  1820. X    SVCXPRT *xprt;
  1821. X{
  1822. X
  1823. X    svcerr_auth(xprt, AUTH_TOOWEAK);
  1824. X}
  1825. X
  1826. X/*
  1827. X * Program unavailable error reply
  1828. X */
  1829. Xvoid 
  1830. Xsvcerr_noprog(xprt)
  1831. X    register SVCXPRT *xprt;
  1832. X{
  1833. X    struct rpc_msg rply;  
  1834. X
  1835. X    rply.rm_direction = REPLY;   
  1836. X    rply.rm_reply.rp_stat = MSG_ACCEPTED;  
  1837. X    rply.acpted_rply.ar_verf = xprt->xp_verf;  
  1838. X    rply.acpted_rply.ar_stat = PROG_UNAVAIL;
  1839. X    SVC_REPLY(xprt, &rply);
  1840. X}
  1841. X
  1842. X/*
  1843. X * Program version mismatch error reply
  1844. X */
  1845. Xvoid  
  1846. Xsvcerr_progvers(xprt, low_vers, high_vers)
  1847. X    register SVCXPRT *xprt; 
  1848. X    u_long low_vers;
  1849. X    u_long high_vers;
  1850. X{
  1851. X    struct rpc_msg rply;
  1852. X
  1853. X    rply.rm_direction = REPLY;
  1854. X    rply.rm_reply.rp_stat = MSG_ACCEPTED;
  1855. X    rply.acpted_rply.ar_verf = xprt->xp_verf;
  1856. X    rply.acpted_rply.ar_stat = PROG_MISMATCH;
  1857. X    rply.acpted_rply.ar_vers.low = low_vers;
  1858. X    rply.acpted_rply.ar_vers.high = high_vers;
  1859. X    SVC_REPLY(xprt, &rply);
  1860. X}
  1861. X
  1862. X/* ******************* SERVER INPUT STUFF ******************* */
  1863. X
  1864. X/*
  1865. X * Get server side input from some transport.
  1866. X *
  1867. X * Statement of authentication parameters management:
  1868. X * This function owns and manages all authentication parameters, specifically
  1869. X * the "raw" parameters (msg.rm_call.cb_cred and msg.rm_call.cb_verf) and
  1870. X * the "cooked" credentials (rqst->rq_clntcred).  However, this function
  1871. X * does not know the structure of the cooked credentials, so it make the
  1872. X * following two assumptions: a) the structure is contiguous (no pointers), and
  1873. X * b) the structure size does not exceed RQCRED_SIZE bytes. 
  1874. X * In all events, all three parameters are freed upon exit from this routine.
  1875. X * The storage is trivially management on the call stack in user land, but
  1876. X * is mallocated in kernel land.
  1877. X */
  1878. Xvoid
  1879. Xsvc_getreq(rdfds)
  1880. X    int rdfds;
  1881. X{
  1882. X    register enum xprt_stat stat;
  1883. X    struct rpc_msg msg;
  1884. X    int prog_found;
  1885. X    u_long low_vers;
  1886. X    u_long high_vers;
  1887. X    struct svc_req r;
  1888. X    register int sock;
  1889. X    register int readfds = rdfds & svc_fds;
  1890. X    register SVCXPRT *xprt;
  1891. X    char cred_area[2*MAX_AUTH_BYTES + RQCRED_SIZE];
  1892. X    msg.rm_call.cb_cred.oa_base = cred_area;
  1893. X    msg.rm_call.cb_verf.oa_base = &(cred_area[MAX_AUTH_BYTES]);
  1894. X    r.rq_clntcred = &(cred_area[2*MAX_AUTH_BYTES]);
  1895. X
  1896. X    for (sock = 0; readfds != 0; sock++, readfds >>= 1) {
  1897. X        if ((readfds & 1) != 0) {
  1898. X        /* sock has input waiting */
  1899. X        xprt = xports[sock];
  1900. X        /* now receive msgs from xprtprt (support batch calls) */
  1901. X        do {
  1902. X            if (SVC_RECV(xprt, &msg)) {
  1903. X
  1904. X                /* now find the exported program and call it */
  1905. X                register struct svc_callout *s;
  1906. X                enum auth_stat why;
  1907. X
  1908. X                r.rq_xprt = xprt;
  1909. X                r.rq_prog = msg.rm_call.cb_prog;
  1910. X                r.rq_vers = msg.rm_call.cb_vers;
  1911. X                r.rq_proc = msg.rm_call.cb_proc;
  1912. X                r.rq_cred = msg.rm_call.cb_cred;
  1913. X                /* first authenticate the message */
  1914. X                if ((why= _authenticate(&r, &msg)) != AUTH_OK) {
  1915. X                    svcerr_auth(xprt, why);
  1916. X                    goto call_done;
  1917. X                }
  1918. X                /* now match message with a registered service*/
  1919. X                prog_found = FALSE;
  1920. X                low_vers = 0 - 1;
  1921. X                high_vers = 0;
  1922. X                for (s = svc_head; s != NULL_SVC; s = s->sc_next) {
  1923. X                    if (s->sc_prog == r.rq_prog) {
  1924. X                        if (s->sc_vers == r.rq_vers) {
  1925. X                            (*s->sc_dispatch)(&r, xprt);
  1926. X                            goto call_done;
  1927. X                        }  /* found correct version */
  1928. X                        prog_found = TRUE;
  1929. X                        if (s->sc_vers < low_vers)
  1930. X                            low_vers = s->sc_vers;
  1931. X                        if (s->sc_vers > high_vers)
  1932. X                            high_vers = s->sc_vers;
  1933. X                    }   /* found correct program */
  1934. X                }
  1935. X                /*
  1936. X                 * if we got here, the program or version
  1937. X                 * is not served ...
  1938. X                 */
  1939. X                if (prog_found)
  1940. X                    svcerr_progvers(xprt,
  1941. X                    low_vers, high_vers);
  1942. X                else
  1943. X                     svcerr_noprog(xprt);
  1944. X                /* Fall through to ... */
  1945. X            }
  1946. X        call_done:
  1947. X            if ((stat = SVC_STAT(xprt)) == XPRT_DIED){
  1948. X                SVC_DESTROY(xprt);
  1949. X                break;
  1950. X            }
  1951. X        } while (stat == XPRT_MOREREQS);
  1952. X        }
  1953. X    }
  1954. X}
  1955. X
  1956. X
  1957. X/*
  1958. X * This is the rpc server side idle loop
  1959. X * Wait for input, call server program.
  1960. X */
  1961. Xvoid
  1962. Xsvc_run()
  1963. X{
  1964. X    int readfds;
  1965. X
  1966. X    while (TRUE) {
  1967. X        readfds = svc_fds;
  1968. X        switch (select(32, &readfds, (int *)0, (int *)0,
  1969. X            (struct timeval *)0)) {
  1970. X
  1971. X        case -1:
  1972. X            if (errno == EINTR)
  1973. X                continue;
  1974. X            else {
  1975. X                perror("svc.c: - Select failed");
  1976. X                return;
  1977. X            }
  1978. X        case 0:
  1979. X            continue;
  1980. X        default:
  1981. X            svc_getreq(readfds);
  1982. X        }
  1983. X    }
  1984. X}
  1985. SHAR_EOF
  1986. if test 10663 -ne "`wc -c < 'rpc/rpclib/svc.c'`"
  1987. then
  1988.     echo shar: "error transmitting 'rpc/rpclib/svc.c'" '(should have been 10663 characters)'
  1989. fi
  1990. chmod 444 'rpc/rpclib/svc.c'
  1991. fi
  1992. exit 0
  1993. #    End of shell archive
  1994.  
  1995.